package com.chexiaoy.lab.service;

import com.chexiaoy.lab.domain.Driver;
import org.apache.commons.csv.CSVFormat;
import org.apache.commons.csv.CSVRecord;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.core.io.ClassPathResource;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * Created by alickgeng on 16/8/12.
 */
@Component
public class DriverService implements ApplicationListener<ContextRefreshedEvent> {


    public static final int SECURITY = 1;
    public static final int COMPANY = 2;
    public static final int DISTANCE = 3;
    public static final int PRICE = 4;
    public static final int DEFINE = 5;

    private static Logger logger = LoggerFactory.getLogger(DriverService.class);

    private List<Driver> onDrivers; // 在线司机

    private List<Driver> offDriver; // 不在线的司机

    private List<Driver> sortedDrivers; //已经排序的司机包括在线和不在线的
    private int type; // 排序方式

    public List<Driver> getSortedDrivers() {
        return sortedDrivers;
    }

    public void loadData(String path) {
        List<Driver> onDrivers = new ArrayList<>();
        List<Driver> offDrivers = new ArrayList<>();

        try {
//            Also, make sure you are using resource.getInputStream() not resource.getFile() when loading from inside a jar file.
//            File file = ResourceUtils.getFile("classpath:" + path);
            ClassPathResource resource = new ClassPathResource(path);
            try (InputStream inputStream = resource.getInputStream(); Reader reader = new InputStreamReader(inputStream)) {

                Iterable<CSVRecord> records = CSVFormat.EXCEL.parse(reader);
                int i = 0;
                for (CSVRecord record : records) {
                    i++;
                    if (i == 1) {
                        continue;// 第一行是标题
                    }
                    Driver driver = new Driver();
                    driver.setName(record.get(0));
                    driver.setPhone(record.get(1));
                    driver.setId(record.get(2));
                    driver.setCoordinate(record.get(3));
                    driver.setDrivingCnt(record.get(4));
                    driver.setAge(record.get(5));
                    driver.setExamineTime(record.get(6));
                    driver.setScore(record.get(7));
                    driver.setServiceRating(record.get(8));
                    driver.setSecurityRating(record.get(9));
                    driver.setDistance(record.get(10));
                    driver.setInfo(record.get(11));
                    if (driver.getCoordinate() == null || driver.getCoordinate().length() == 0) {
                        offDrivers.add(driver);
                    } else {
                        onDrivers.add(driver);
                    }

                }
            }

        } catch (IOException e) {
            e.printStackTrace();
        }
        this.onDrivers = onDrivers;
        this.offDriver = offDrivers;
        logger.info("在线司机 {}, 不在线司机{}", this.onDrivers.size(), this.offDriver.size());

    }

    @Override
    public void onApplicationEvent(ContextRefreshedEvent contextRefreshedEvent) {
        this.loadData("driver.csv");
    }

    /**
     * 按条件排序
     *
     * @param type 条件类型
     * @return 排序了的司机
     */
    public List<Driver> sortDrivers(int type) {

        this.type = type;
        List<Driver> tmp = new ArrayList<>();
        tmp.addAll(this.onDrivers);
        switch (type) {
            case SECURITY:
                Collections.sort(tmp, (o1, o2) ->
                        Float.parseFloat(o1.getSecurityRating()) - Float.parseFloat(o2.getSecurityRating()) > 0 ?
                                -1 : 1);
                break;
            case DISTANCE:
                Collections.sort(tmp, (o1, o2) ->
                        Float.parseFloat(rmUnit(o1.getDistance())) - Float.parseFloat(rmUnit(o2.getDistance())) > 0 ?
                                1 : -1);
                break;
            case PRICE:
                Collections.reverse(tmp);
                break;
            default:
                break;
        }

        tmp.addAll(this.offDriver);
        this.sortedDrivers = tmp;
        return this.sortedDrivers;
    }

    private String rmUnit(String distance) {
        String lower = distance.toLowerCase();
        if (lower.contains("km")) {
            return lower.replace("km", "0");
        } else {
            return lower;
        }
    }

    public int getType() {
        return type;
    }

    public String getTypeName() {

        switch (this.type) {
            case SECURITY:
                return "安全优先";
            case COMPANY:
                return "公司优先";
            case PRICE:
                return "价格优先";
            case DISTANCE:
                return "距离优先";
            case DEFINE:
                return "自定义";
            default:
                return "默认";
        }
    }
}
